package org.groupg.practice.pool2.demo01;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.groupg.practice.pool2.demo01.model.ComplexObject;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ProducerConsumerExample {
    private final GenericObjectPool<ComplexObject> pool;
    private final ExecutorService executorService;
    private final int numProducers;
    private final int numConsumers;

    public ProducerConsumerExample(int poolSize, int numProducers, int numConsumers) {
        ComplexObjectFactory factory = new ComplexObjectFactory();
        GenericObjectPoolConfig<ComplexObject> config = new GenericObjectPoolConfig<>();
        config.setMaxTotal(poolSize);
        pool = new GenericObjectPool<>(factory, config);
        this.numProducers = numProducers;
        this.numConsumers = numConsumers;
        executorService = Executors.newFixedThreadPool(numProducers + numConsumers);
    }

    public void start() {
        // 创建并启动生产者线程
        for (int i = 0; i < numProducers; i++) {
            executorService.submit(new Producer(pool));
        }

        // 创建并启动消费者线程
        for (int i = 0; i < numConsumers; i++) {
            executorService.submit(new Consumer(pool));
        }
    }

    public void shutdown() {
        executorService.shutdown();
    }

    // 提供对象借用和归还的方法
    public ComplexObject borrowObject() {
        try {
            return pool.borrowObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void returnObject(ComplexObject object) {
        pool.returnObject(object);
    }

    // 其他生产者和消费者逻辑...
}

class Producer implements Runnable {
    private final GenericObjectPool<ComplexObject> pool;

    public Producer(GenericObjectPool<ComplexObject> pool) {
        this.pool = pool;
    }

    @Override
    public void run() {
        try {
            while (!Thread.currentThread().isInterrupted()) {
                ComplexObject obj = pool.borrowObject();
                // 模拟生产操作
                obj.setText("Produced " + System.currentTimeMillis());
                // 模拟使用对象...
                // 返回对象到池
                pool.returnObject(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Consumer implements Runnable {
    private final GenericObjectPool<ComplexObject> pool;

    public Consumer(GenericObjectPool<ComplexObject> pool) {
        this.pool = pool;
    }

    @Override
    public void run() {
        try {
            while (!Thread.currentThread().isInterrupted()) {
                ComplexObject obj = pool.borrowObject();
                // 模拟消费操作
                System.out.println("Consumed: " + obj.getText());
                // 处理对象...
                // 返回对象到池
                pool.returnObject(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}